/*
这个答案参考了知乎上的解析：https://zhuanlan.zhihu.com/p/482698486
原文解析如下：
本题相对比较复杂，需要实现一个gshare。
产生predict_taken的方式是通过一个叫模式匹配表（pattern history table， PHT）的东西
首先题目中历史缓冲区为7个bit，因此PHT的大小为2^7 = 128个。
pattern为 7bit历史缓冲区和7bit程序计数器（PC）按位异或，每个pattern对应一个2bit饱和计数器
模块可以分成training和predicting两部分，分别由train_valid和predict_valid两个信号控制
*/
module top_module(
    input clk,
    input areset,

    input  predict_valid,
    input  [6:0] predict_pc,
    output predict_taken,
    output [6:0] predict_history,

    input train_valid,
    input train_taken,
    input train_mispredicted,
    input [6:0] train_history,
    input [6:0] train_pc
);

	reg[1:0] PHT[127:0];
	integer i;
	always@(posedge clk or posedge areset)begin
		if(areset)begin
			predict_history<=7'd0;
			for(i=0;i<128;i=i+1)
				PHT[i]<=2'b01;
		end
		else if(train_valid)begin
			if(train_mispredicted)begin
				predict_history<={train_history[5:0],train_taken};
			end
			else if(predict_valid)begin
                predict_history <= {predict_history[5:0], predict_taken};				
			end
			else begin
				predict_history <= predict_history;
			end
			if(train_taken)begin
				PHT[train_history ^ train_pc] <= (PHT[train_history ^ train_pc] == 2'b11) ? 2'b11 : (PHT[train_history ^ train_pc] + 1);
			end
			else begin
                PHT[train_history ^ train_pc] <= (PHT[train_history ^ train_pc] == 2'b00) ? 2'b00 : (PHT[train_history ^ train_pc] - 1);
			end
		end
		else if(predict_valid)begin
			predict_history <= {predict_history[5:0], predict_taken};
		end
		else begin
			predict_history <= predict_history;
		end
	end

	assign predict_taken = PHT[predict_history^predict_pc][1];
	
endmodule